package com.bzy.shiro.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Resource;

import com.bzy.common.manager.JedisManager;
import com.bzy.common.util.SerializationUtil;
import com.bzy.shiro.service.ISessionService;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.session.Session;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.stereotype.Service;

@Service(value = "sessionJedisServiceImpl")
public class SessionJedisServiceImpl implements ISessionService {

	@Resource
	JedisManager jedisManager;

	@Override
	public void doCreate(Session session, String keyPattern) throws Exception {
		// TODO Auto-generated method stub
		String key = this.getKey(session.getId(), keyPattern);
		String value = Base64.encodeToString(SerializationUtil.serialize(session));
		jedisManager.set(key, value, -1);
	}

	@Override
	public void doUpdate(Session session, String keyPattern) throws Exception {
		// TODO Auto-generated method stub
		String key = this.getKey(session.getId(), keyPattern);
		String value = Base64.encodeToString(SerializationUtil.serialize(session));
		jedisManager.set(key, value, -1);
	}

	@Override
	public void doDelete(Session session, String keyPattern) throws Exception {
		// TODO Auto-generated method stub
		String key = this.getKey(session.getId(), keyPattern);
		jedisManager.del(key);
	}

	@Override
	public Session doReadSession(Serializable sessionId, String keyPattern) throws Exception {
		// TODO Auto-generated method stub
		Session result = null;
		String key = this.getKey(sessionId, keyPattern);
		String value = jedisManager.get(key, "");
		result = (Session) SerializationUtil.deserialize(Base64.decode(value));
		return result;
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Collection<Session> getAllSessions(String keyPattern) throws Exception {
		// TODO Auto-generated method stub
		Set<String> keys = (Set<String>) this.keys(keyPattern);
		if (!CollectionUtils.isEmpty(keys)) {
			List values = new ArrayList(keys.size());
			for (String key : keys) {
				Session value = (Session) SerializationUtil.deserialize(Base64.decode(jedisManager.get(key, "")));
				if (value != null) {
					values.add(value);
				}
			}
			return Collections.unmodifiableList(values);
		} else {
			return Collections.emptyList();
		}
	}

	private Set<String> keys(String keyPattern) {
		String pattern = "*" + keyPattern + "*";
		Set<String> strKeys = new HashSet<String>();
		Set<byte[]> keys = jedisManager.keys(pattern.getBytes());
		for (byte[] key : keys) {
			strKeys.add((String) new String(key));
		}
		return strKeys;
	}

	private String getKey(Object key, String keyPattern) {
		return keyPattern + ":" + key;
	}

}
